﻿using System;
using System.Text;

namespace jQueryCSharp.ui
{
    /// <summary>
    /// jquery.ui.datepicker
    /// </summary>
    public class DatepickerBuilder : IjQueryCSharpUIBuilder<DatepickerBuilder>
    {
        private const string Template = "$(\"{0}{1}\").datepicker({2});";
        private readonly Datepicker _ui;
        private readonly jQueryCSharpUIBuilder _builder;

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="builder">jQueryCSharpUIBuilder</param>
        public DatepickerBuilder( jQueryCSharpUIBuilder builder )
            : this( builder, "" )
        {
        }

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="builder">jQueryCSharpUIBuilder</param>
        /// <param name="identifier"></param>
        public DatepickerBuilder( jQueryCSharpUIBuilder builder, string identifier )
        {
            _ui = new Datepicker( identifier );
            _builder = builder;
        }

        #region Métodos
        public DatepickerBuilder ID( string value )
        {
            _ui.ID = value;
            return this;
        }

        public DatepickerBuilder Class( string value )
        {
            _ui.Class = value;
            return this;
        }

        /// <summary>
        /// Disables (true) or enables (false) the datepicker. Can be set when initialising (first creating) the datepicker.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder Disabled( bool value )
        {
            _ui.Disabled = value;
            return this;
        }

        /// <summary>
        /// The jQuery selector for another field that is to be updated with the selected date from the datepicker. Use the "altFormat" (http://docs.jquery.com/UI/Datepicker#option-altFormat) setting to change the format of the date within this field. Leave as blank for no alternate field.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder AltField( string value )
        {
            _ui.AltField = value;
            return this;
        }

        /// <summary>
        /// The "dateFormat" (http://docs.jquery.com/UI/Datepicker#option-dateFormat) to be used for the "altField" (http://docs.jquery.com/UI/Datepicker#option-altField) option. This allows one date format to be shown to the user for selection purposes, while a different format is actually sent behind the scenes. For a full list of the possible formats see the "formatDate" (http://docs.jquery.com/UI/Datepicker/formatDate) function
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder AltFormat( string value )
        {
            _ui.AltFormat = value;
            return this;
        }

        /// <summary>
        /// The text to display after each date field, e.g. to show the required format.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder AppendText( string value )
        {
            _ui.AppendText = value;
            return this;
        }

        /// <summary>
        /// Set to true to automatically resize the input field to accomodate dates in the current "dateFormat" (http://docs.jquery.com/UI/Datepicker#option-dateFormat).
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder AutoSize( bool value )
        {
            _ui.AutoSize = value;
            return this;
        }

        /// <summary>
        /// The URL for the popup button image. If set, buttonText becomes the alt value and is not directly displayed.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder ButtonImage( string value )
        {
            _ui.ButtonImage = value;
            return this;
        }

        /// <summary>
        /// Set to true to place an image after the field to use as the trigger without it appearing on a button.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder ButtonImageOnly( bool value )
        {
            _ui.ButtonImageOnly = value;
            return this;
        }

        /// <summary>
        /// The text to display on the trigger button. Use in conjunction with showOn equal to 'button' or 'both'.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder ButtonText( string value )
        {
            _ui.ButtonText = value;
            return this;
        }

        /// <summary>
        /// A function to calculate the week of the year for a given date. The default implementation uses the ISO 8601 definition: weeks start on a Monday; the first week of the year contains the first Thursday of the year.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder CalculateWeek( string value )
        {
            _ui.CalculateWeek = value;
            return this;
        }

        /// <summary>
        /// Allows you to change the month by selecting from a drop-down list. You can enable this feature by setting the attribute to true.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder ChangeMonth( bool value )
        {
            _ui.ChangeMonth = value;
            return this;
        }

        /// <summary>
        /// Allows you to change the year by selecting from a drop-down list. You can enable this feature by setting the attribute to true. Use the yearRange option to control which years are made available for selection
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder ChangeYear( bool value )
        {
            _ui.ChangeYear = value;
            return this;
        }

        /// <summary>
        /// The text to display for the close link. This attribute is one of the regionalisation attributes. Use the showButtonPanel to display this button.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder CloseText( string value )
        {
            _ui.CloseText = value;
            return this;
        }

        /// <summary>
        /// When true entry in the input field is constrained to those characters allowed by the current dateFormat.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder ConstrainInput( bool value )
        {
            _ui.ConstrainInput = value;
            return this;
        }

        /// <summary>
        /// The text to display for the current day link. This attribute is one of the regionalisation attributes. Use the showButtonPanel to display this button.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder CurrentText( string value )
        {
            _ui.CurrentText = value;
            return this;
        }

        /// <summary>
        /// The format for parsed and displayed dates. This attribute is one of the regionalisation attributes. For a full list of the possible formats see the "formatDate" (http://docs.jquery.com/UI/Datepicker/formatDate) function.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder DateFormat( string value )
        {
            _ui.DateFormat = value;
            return this;
        }

        /// <summary>
        /// The list of long day names, starting from Sunday, for use as requested via the dateFormat setting. They also appear as popup hints when hovering over the corresponding column headings. This attribute is one of the regionalisation 
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder DayNames( string value )
        {
            _ui.DayNamesMin = value;
            return this;
        }

        /// <summary>
        /// The list of minimised day names, starting from Sunday, for use as column headers within the datepicker. This attribute is one of the regionalisation attributes.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder DayNamesMin( string value )
        {
            _ui.DayNamesMin = value;
            return this;
        }

        /// <summary>
        /// The list of abbreviated day names, starting from Sunday, for use as requested via the dateFormat setting. This attribute is one of the regionalisation attributes.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder DayNamesShort( string value )
        {
            _ui.DayNamesShort = value;
            return this;
        }

        /// <summary>
        /// Set the date to highlight on first opening if the field is blank. Specify either an actual date via a Date object or as a string in the current dateFormat, or a number of days from today (e.g. +7) or a string of values and periods ('y' for years, 'm' for months, 'w' for weeks, 'd' for days, e.g. '+1m +7d'), or null for today.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder DefaultDate( string value )
        {
            _ui.DefaultDate = value;
            return this;
        }

        /// <summary>
        /// Control the speed at which the datepicker appears, it may be a time in milliseconds or a string representing one of the three predefined speeds ("slow", "normal", "fast").
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder Duration( string value )
        {
            _ui.Duration = value;
            return this;
        }

        /// <summary>
        /// Set the first day of the week: Sunday is 0, Monday is 1, ... This attribute is one of the regionalisation attributes.
        /// </summary>
        /// <param name="value">int</param>
        /// <returns></returns>
        public DatepickerBuilder FirstDay( int value )
        {
            _ui.FirstDay = value;
            return this;
        }

        /// <summary>
        /// When true the current day link moves to the currently selected date instead of today.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder GoToCurrent( bool value )
        {
            _ui.GoToCurrent = value;
            return this;
        }

        /// <summary>
        /// Normally the previous and next links are disabled when not applicable (see minDate/maxDate
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder HideIfNoPrevNext( bool value )
        {
            _ui.HideIfNoPrevNext = value;
            return this;
        }

        /// <summary>
        /// True if the current language is drawn from right to left. This attribute is one of the regionalisation attributes.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder IsRTL( bool value )
        {
            _ui.IsRTL = value;
            return this;
        }

        /// <summary>
        /// Set a maximum selectable date via a Date object or as a string in the current dateFormat, or a number of days from today (e.g. +7) or a string of values and periods ('y' for years, 'm' for months, 'w' for weeks, 'd' for days, e.g. '+1m +1w'), or null for no limit.
        /// </summary>
        /// <param name="value">DateTime</param>
        /// <returns></returns>
        public DatepickerBuilder MaxDate( DateTime value )
        {
            _ui.MaxDate = value;
            return this;
        }

        /// <summary>
        /// Set a minimum selectable date via a Date object or as a string in the current dateFormat, or a number of days from today (e.g. +7) or a string of values and periods ('y' for years, 'm' for months, 'w' for weeks, 'd' for days, e.g. '-1y -1m'), or null for no limit.
        /// </summary>
        /// <param name="value">DateTime</param>
        /// <returns></returns>
        public DatepickerBuilder MinDate( DateTime value )
        {
            _ui.MinDate = value;
            return this;
        }

        /// <summary>
        /// The list of full month names, for use as requested via the dateFormat setting. This attribute is one of the regionalisation attributes.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder MonthNames( string value )
        {
            _ui.MonthNames = value;
            return this;
        }

        /// <summary>
        /// he list of abbreviated month names, as used in the month header on each datepicker and as requested via the dateFormat setting. This attribute is one of the regionalisation attributes.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder MonthNamesShort( string value )
        {
            _ui.MonthNamesShort = value;
            return this;
        }

        /// <summary>
        /// When true the formatDate function is applied to the prevText, nextText, and currentText values before display, allowing them to display the target month names for example.
        /// </summary>
        /// <param name="value">Bool</param>
        /// <returns></returns>
        public DatepickerBuilder NavigationAsDateFormat( bool value )
        {
            _ui.NavigationAsDateFormat = value;
            return this;
        }

        /// <summary>
        /// The text to display for the next month link. This attribute is one of the regionalisation attributes. With the standard ThemeRoller styling, this value is replaced by an icon.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder NextText( string value )
        {
            _ui.NextText = value;
            return this;
        }

        /// <summary>
        /// et how many months to show at once. The value can be a straight integer, or can be a two-element array to define the number of rows and columns to display.
        /// </summary>
        /// <param name="value">int</param>
        /// <returns></returns>
        public DatepickerBuilder NumberOfMonths( int value )
        {
            _ui.NumberOfMonths = value;
            return this;
        }

        /// <summary>
        /// The text to display for the previous month link. This attribute is one of the regionalisation attributes. With the standard ThemeRoller styling, this value is replaced by an icon.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder PrevText( string value )
        {
            _ui.PrevText = value;
            return this;
        }

        /// <summary>
        /// When true days in other months shown before or after the current month are selectable. This only applies if showOtherMonths is also true.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder SelectOtherMonths( bool value )
        {
            _ui.SelectOtherMonths = value;
            return this;
        }

        /// <summary>
        /// Set the cutoff year for determining the century for a date (used in conjunction with dateFormat 'y'). If a numeric value (0-99) is provided then this value is used directly. If a string value is provided then it is converted to a number and added to the current year. Once the cutoff year is calculated, any dates entered with a year value less than or equal to it are considered to be in the current century, while those greater than it are deemed to be in the previous century.
        /// </summary>
        /// <param name="value">int</param>
        /// <returns></returns>
        public DatepickerBuilder ShortYearCutoff( int value )
        {
            _ui.ShortYearCutoff = value;
            return this;
        }

        /// <summary>
        /// Set the name of the animation used to show/hide the datepicker. Use 'show' (the default), 'slideDown', 'fadeIn', any of the show/hide "jQuery UI effects" (http://docs.jquery.com/UI/Effects), or '' for no animation.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder ShowAnim( string value )
        {
            _ui.ShowAnim = value;
            return this;
        }

        /// <summary>
        /// Whether to show the button panel.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder ShowButtonPanel( bool value )
        {
            _ui.ShowButtonPanel = value;
            return this;
        }

        /// <summary>
        /// Specify where in a multi-month display the current month shows, starting from 0 at the top/left.
        /// </summary>
        /// <param name="value">int</param>
        /// <returns></returns>
        public DatepickerBuilder ShowCurrentAtPos( int value )
        {
            _ui.ShowCurrentAtPos = value;
            return this;
        }

        /// <summary>
        /// Whether to show the month after the year in the header. This attribute is one of the regionalisation attributes.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder ShowMonthAfterYear( bool value )
        {
            _ui.ShowMonthAfterYear = value;
            return this;
        }

        /// <summary>
        /// Have the datepicker appear automatically when the field receives focus ('focus'), appear only when a button is clicked ('button'), or appear when either event takes place ('both').
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder ShowOn( string value )
        {
            _ui.ShowOn = value;
            return this;
        }

        /// <summary>
        /// Display dates in other months (non-selectable) at the start or end of the current month. To make these days selectable use selectOtherMonths.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder ShowOtherMonths( bool value )
        {
            _ui.ShowOtherMonths = value;
            return this;
        }

        /// <summary>
        /// When true a column is added to show the week of the year. The calculateWeek option determines how the week of the year is calculated. You may also want to change the firstDay option.
        /// </summary>
        /// <param name="value">bool</param>
        /// <returns></returns>
        public DatepickerBuilder ShowWeek( bool value )
        {
            _ui.ShowWeek = value;
            return this;
        }

        /// <summary>
        /// Set how many months to move when clicking the Previous/Next links.
        /// </summary>
        /// <param name="value">int</param>
        /// <returns></returns>
        public DatepickerBuilder StepMonths( int value )
        {
            _ui.StepMonths = value;
            return this;
        }

        /// <summary>
        /// The text to display for the week of the year column heading. This attribute is one of the regionalisation attributes. Use showWeek to display this column.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder WeekHeader( string value )
        {
            _ui.WeekHeader = value;
            return this;
        }
        
        /// <summary>
        /// Control the range of years displayed in the year drop-down: either relative to today's year (-nn:+nn), relative to the currently selected year (c-nn:c+nn), absolute (nnnn:nnnn), or combinations of these formats (nnnn:-nn). 
        /// Note that this option only affects what appears in the drop-down, to restrict which dates may be selected use the minDate and/or maxDate options.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder YearRange( string value )
        {
            _ui.YearRange = value;
            return this;
        }

        /// <summary>
        /// dditional text to display after the year in the month headers. This attribute is one of the regionalisation attributes.
        /// </summary>
        /// <param name="value">string</param>
        /// <returns></returns>
        public DatepickerBuilder YearSuffix( string value )
        {
            _ui.YearSuffix = value;
            return this;
        }
        #endregion

        #region Override
        public new jQueryCSharpUIBuilder ToString( )
        {
            var sb = new StringBuilder( );

            var sinal = String.IsNullOrEmpty( _ui.Class ) ? "#" : ".";
            var id = String.IsNullOrEmpty( _ui.Class ) ? _ui.ID : _ui.Class;

            sb.AppendFormat( Template, sinal, id, _ui );

            _builder.Append( sb.ToString( ) );

            return _builder;
        }
        #endregion

    }
}
